package composite

type PeopleResource interface {
	CalculateSalary() int
	GetEmployeeNum() int
	GetID() string
	Search(id string) PeopleResource
}

type Department struct {
	ID       string
	SubNodes map[string]PeopleResource
}

func NewDepartment(id string) *Department {
	return &Department{
		ID:       id,
		SubNodes: map[string]PeopleResource{},
	}
}

func (d *Department) AddSubNode(node PeopleResource) {
	d.SubNodes[node.GetID()] = node
}

func (d *Department) CalculateSalary() int {
	salary := 0
	for _, node := range d.SubNodes {
		salary += node.CalculateSalary()
	}

	return salary
}

func (d *Department) GetEmployeeNum() int {
	num := 0
	for _, node := range d.SubNodes {
		num += node.GetEmployeeNum()
	}

	return num
}

func (d *Department) GetID() string {
	return d.ID
}

func (d *Department) Search(id string) PeopleResource {
	// 1. 如果本部门ID匹配，直接返回
	if d.ID == id {
		return d
	}

	// 2. 否则，递归搜索子节点
	for _, node := range d.SubNodes {
		if result := node.Search(id); result != nil {
			return result
		}
	}

	// 3. 未找到返回 nil
	return nil
}

type Employee struct {
	ID     string
	Salary int
}

func NewEmployee(id string, salary int) *Employee {
	return &Employee{
		ID:     id,
		Salary: salary,
	}
}

func (e *Employee) CalculateSalary() int {
	return e.Salary
}

func (e *Employee) GetEmployeeNum() int {
	return 1
}

func (e *Employee) GetID() string {
	return e.ID
}

func (e *Employee) Search(id string) PeopleResource {
	if e.ID == id {
		return e
	}
	return nil
}
